
/**
 * User order entity.
 * @see ProviderOrder
 */
@Entity
@Table(name = "user_order")
public class UserOrder extends UserBaseInfo {
	private static final long serialVersionUID = -715658171546235257L;
	
	@Id
	@Column(name = "id")
	@JsonSerialize(using = OrderIdSerializer.class)
	private long id;

	/** 关联用户ID */
	@Column(name = "user_id")
	private int userId;

	/**联合主键*/
	@Id
	private UserBusinessOrderPk id;
	@Embeddable
	public static class UserBusinessOrderPk extends BaseBean {

		/** 用户订单ID */
		@Column(name = "user_order_id")
		private long userOrderId;
		/** 供应商ID */
		@Column(name = "provider_id")
		private int providerId;
	}

	
	/**
	 * many to many
	 * user_order id
	 * user_business_order  user_order_id business_bill_id
	 * provider_business_bill id
	 * */
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinTable(name = "user_business_order", 
			joinColumns = { @JoinColumn(name = "user_order_id") }, 
			inverseJoinColumns = { @JoinColumn(name = "business_bill_id") })
	private ProviderBusinessBill businessBill;
	

	/** 接单订单编号  */
	@Column(name = "provider_order_id", columnDefinition = "bigint(32) null")
	private Long providerOrderId;
	
	
	private @Embedded UserOrderInsurance insurance;
	
	/**
	 * 用户订单交付状态
	 * @see DeliveryStatus
	 */
	@Column(name = "delivery_status", columnDefinition = "int not null default 10")
	private int deliveryStatus = DeliveryStatus.WatingGenerateBusinessBill.value;

	/** 创建时间 */
	@Column(name = "create_time", columnDefinition="timestamp not null default now()")
	private Timestamp createTime;

	
	/** 参保用户所在公司 
	* many to many
	*/
	@ManyToOne(fetch=FetchType.LAZY)
	@JoinColumn(name = "company_id", insertable = false, updatable = false)
	private Company company;
	
	
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "city_id", insertable = false, updatable = false)
	private City city;
	
	
	/** 税率 */
	@Column(name = "tax_rate", columnDefinition = "int not null default 0")
	private int taxRate;

	/**
	 * 用户订单状态
	 * @author tanghuabo
	 */
	public static enum UserOrderStatus implements EnumWithValue {
		/** 初始化生成，待确认订单 */
		Created(10, "待确认"),
		
		/** 客户订单确认 */
		Confirmed(20, "待支付"),
		
		/** 待办理 */
		Handing(30, "办理中"),
		
		/** 已办理成功 */
		Success(40, "办理成功"),
		
		/** 办理成功并补收 */
		SuccessAndRecharge(50, "办理成功并补收"),
		
		/** 办理成功并退费 */
		SuccessAndReturn(60, "办理成功并退费"),
		
		/** 已办理失败 */
		Failed(70, "办理失败并退费"),
		
		/** 关闭 */
		Closed(80, "已关闭"),
		
		/** 客户已支付 */
		@Deprecated
		Prepaid(-1, "已支付"),
		
		/** 办理中 */
		@Deprecated
		Handing2(-1, "办理中"),
		
		@Deprecated
		FinishedSuccess(-1, "办理完成成功"),
		
		@Deprecated
		FinishedFailed(-1, "办理完成失败");
		
		public final int value;
		public final String name;
		private UserOrderStatus(int value, String name) {
			this.value = value;
			this.name = name;
		}
		
		public static final UserOrderStatus getStatus(int typeValue) {
			return EnumUtils.enumForValue(UserOrderStatus.class, typeValue);
		}

		@Override
		public int getValue() {
			return value;
		}
		
		public static final int[] activeForProviderSales() {
			return new int[] { Prepaid.value, Handing.value, Handing2.value, Success.value };
		}
		
		/**
		 * @return 有效单:已支付、待办理、办理中、办理成功、办理失败
		 * @author owen.he
		 */
		public static final Integer[] effectiveUserOrderStatus() {
			return new Integer[] { Prepaid.value, Handing.value, Success.value, Handing2.value, Failed.value };
		}

	}
	
	/**
	 * 交付状态
	 * @author tony
	 */
	public static enum DeliveryStatus implements EnumWithValue{
		WatingGenerateBusinessBill(10, "待生成业务账单"),
		WatingConfirmBusinessBill(20, "待确认业务账单"),
		WatingPayBusinessFee(30, "待支付业务费"),
		PaiedBusinessFee(40, "已支付业务费"),
		WatingGenerateServiceBill(50, "待生成服务费账单"),
		WatingConfirmServiceBill(60, "待确认服务费账单"),
		WaitingPayServiceFee(70, "待支付服务费"),
		PaiedServiceFee(80, "已支付服务费");
		
		public final int value;
		public final String name;
		
		DeliveryStatus(int value, String name){
			this.name = name;
			this.value = value;
		}

		@Override
		public int getValue() {
			return this.value;
		}
		
		 public static final DeliveryStatus deliveryStatus(final int type) {
			 return EnumUtils.enumForValue(DeliveryStatus.class, type);
		 }
	}
	
	/**
	 * 状态(给供应商使用的状态)
	 * @author tanghuabo
	 */
	public static enum Status {
		/** 新增 */
		New(1, "增员", true),
		/** 续缴 */
		Continue(2, "续保", true),
		/** 停缴 */
		Stop(3, "停保", false),
		/** 未缴纳 */
		None(4, "未缴纳", false),
		/** 补缴 */
		Resave(5, "补缴", true);
		
		public final int value;
		public final String name;
		public final boolean isPay;
		
		Status(int value, String name, boolean isPay) {
			this.value = value;
			this.name = name;
			this.isPay = isPay;
		}
		
		public boolean isPay() {
			return this.isPay;
		}
		
		public static final Status status(int typeValue) {
			switch (typeValue) {
			case 1:
				return New;
			case 2:
				return Continue;
			case 3:
				return Stop;
			case 4:
				return None;
			case 5:
				return Resave;
			default:
				throw new IllegalArgumentException("Illegal status value:'" + typeValue + "'");	
			}
		}
	}
	
	public UserOrder() {
	}
	
	/**
	 * 构造UserOrder并复制用户基础的一些信息
	 * @param userBaseInfo
	 */
	public UserOrder(UserBaseInfo userBaseInfo) {
		super(userBaseInfo);
	}


	public int getCpfStatus() {
		return this.cpf==null ? 0 : this.cpf.getCpfStatus();
	}

	public String getInsurancePlanName() {
		return this.insurance==null ? null : this.insurance.getInsurancePlanName();
	}

	public String getCpfPlanName() {
		return this.cpf==null ? null : this.cpf.getCpfPlanName();
	}

 	interface EnumWithValue  {
		public int getValue();
	}
	

	class EnumUtils {

		public static final <T extends Enum<T> & EnumWithValue> T enumForValue(Class<T> type, int value) {
				final EnumSet<T> allOf = EnumSet.allOf(type);
				final Iterator<T> iterator = allOf.iterator();
				while (iterator.hasNext()) {
					final T next = iterator.next();
					if (next.getValue() == value) {
						return next;
					}
				}
				throw new IllegalArgumentException("Unknow enum value: '" + value + "'");
		}
	
		public static <T extends Enum<T> & EnumWithValue> List<Integer> enumForValueList(Class<T> type) {
			List<Integer> valueList = new ArrayList<Integer>();
			final Iterator<T> iterator = EnumSet.allOf(type).iterator();
			while (iterator.hasNext()) {
				valueList.add(iterator.next().getValue());
			}
			return valueList;
		}
	}

}

}

//many to many HibernateDao.java



